/*
 * tsymbol.c
 *
 *  Created on: Jan 10, 2016
 *      Author: root
 */

#include <string.h>
#include "../basic/operator.h"

/*
// (in-global-package)
Cell* op_in_global_package(Scheme *sc) {
	sc->package = &g_nil;
	return s_return_helper(sc, &g_true);
}

// (in-package "funny.core.basis")
// (in-package "funny.core.basis" symbol)
Cell* op_in_package(Scheme *sc) {
	Cell *package = first(sc->args);
	Cell *symbol = second(sc->args);
	TYPE_CHECK(sc, package, TYPE_STRING);
	Cell *result = &g_true;
	if (symbol == &g_nil) {
		sc->package = package;
	} else {
		// result = find_symbol_in_package();
	}
	return s_return_helper(sc, result);
}
*/





char *symbol_name(Cell* sym) {
	return car(sym)->_string;
}

Cell* find_global_symbol(Scheme *sc, const char *name) {
	int location = hash_fn(name, sc->globalObjects->_longValue);
	Cell* sym_list;
	for (sym_list = get_vector_item(sc->globalObjects, location);
			sym_list != &g_nil; sym_list = cdr(sym_list)) {
		char *s = symbol_name(car(sym_list));
		if (strcasecmp(name, s) == 0)
			return car(sym_list); //返回一个符号
	}
	return &g_nil;
}

//查找一个符号
static Cell* oblist_find_by_name(Scheme *sc, const char *name) {
	int location = hash_fn(name, sc->globalObjects->_longValue);
	Cell* sym_list;
	for (sym_list = get_vector_item(sc->globalObjects, location);
			sym_list != &g_nil; sym_list = cdr(sym_list)) {
		char *s = symbol_name(car(sym_list));
		if (strcasecmp(name, s) == 0)
			return car(sym_list); //返回一个符号
	}
	return &g_nil;
}

////////// symbol has defined package, or say namespace

// 创建一个新的符号
static Cell* oblist_add_by_name(Scheme *sc, const char *name) {
	//符号内部像这样("name1")
	Cell* sym = immutable_cons(sc, make_string(sc, name), &g_nil);
	// (sym)->_flag = T_SYMBOL; //类型为符号
	(sym)->_type = SYMBOL_TYPE; //类型为符号
	(sym)->_name = name;
	set_immutable(car(sym));
	int location = hash_fn(name, sc->globalObjects->_longValue);
	//get_vector_item(sc->oblist, location) 等价于  (vector-ref sc->oblist location)    求值结果是一个符号链表 (symbol ...)
	set_vector_item(sc->globalObjects, location,
			immutable_cons(sc, sym, get_vector_item(sc->globalObjects, location))); //将新的符号加入链表头部
	return sym;
}

/*
Cell* make_symbol(Scheme *sc, const char *name) {
	sc->obj;
	sc->package;

	oblist_find_by_name(sc, sc->obj);
}
*/

//添加一个符号，如果有这个符号，就返回已有的那个
Cell* make_symbol(Scheme *sc, const char *name) {
	/* first check oblist */
	Cell* sym = oblist_find_by_name(sc, name);
	if (sym != &g_nil)
		return sym;
	return oblist_add_by_name(sc, name);
}

// (defined? var_name)
// (defined? var_name env)
Cell* op_defp(Scheme *sc) {
	Cell *env;
	if (rest(sc->args) != &g_nil)
		env = second(sc->args);
	else
		env = sc->env;
	int istrue = (find_slot_in_env(sc, env, first(sc->args), TRUE) != &g_nil);
	sc->returnValue = (istrue) ? &g_true : &g_false;
	return pop_callstack(sc);
}

void init_symbol_operators(Scheme *sc) {
	ADD_OPERATOR(sc, "defined?", defp);
}

void init_symbol_constants(Scheme *sc) {
	cell_symbol_lambda = make_symbol(sc, SYMBOL_LAMBDA);
	cell_symbol_quote = make_symbol(sc, SYMBOL_QUOTE);
	cell_symbol_this = make_symbol(sc, SYMBOL_THIS);
}

//symbol->string
